/*
 * Copyright 2025-2026 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package glz.hawk.springboot.poc;

import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.validation.annotation.Validated;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.validation.beanvalidation.SpringConstraintValidatorFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * This class is responsible for
 *
 * @author Zhang Peng
 */
@SpringBootApplication
public class Application {


    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args);
        System.out.println(applicationContext.toString());
        System.out.println(applicationContext.getBean(PocProperties.class).getEmail());
        applicationContext.close();
    }

    @ConfigurationProperties("glz.hawk.springboot.poc")
    @Validated
    @ConditionalOnMissingBean
    @Bean
    public PocProperties pocProperties() {
        return new PocProperties();
    }

    @ConfigurationProperties("glz.hawk.springboot.poc2")
    @Validated
    @ConditionalOnMissingBean
    @Bean
    public PocProperties pocProperties2() {
        return new PocProperties();
    }

    @Bean("hibernateValidator")
    public LocalValidatorFactoryBean validator(MessageSource messageSource, ApplicationContext applicationContext) {
        LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
        // 1. 配置消息源
        factoryBean.setValidationMessageSource(messageSource);

        // 设置消息的翻译器，ParameterMessageInterpolator不依赖于javax.el
//        factoryBean.setMessageInterpolator(new ParameterMessageInterpolator());

        // 2. 支持依赖注入的验证器工厂
        factoryBean.setConstraintValidatorFactory(
            new SpringConstraintValidatorFactory(
                applicationContext.getAutowireCapableBeanFactory()
            )
        );

        // 3. 配置验证参数
        Properties validationProperties = new Properties();
        validationProperties.put("hibernate.validator.fail_fast", "false");
        factoryBean.setValidationProperties(validationProperties);

        return factoryBean;
    }

    @Bean
    MessageSource validatorMessageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setDefaultEncoding("UTF-8");
        messageSource.setCacheSeconds(60); // 缓存60秒
        messageSource.setConcurrentRefresh(true);
        // 设置自定义消息文件位置
        messageSource.setBasenames("classpath:validation-messages");

        // 设置默认编码
        messageSource.setDefaultEncoding("UTF-8");

        // 设置缓存时间（秒）
        messageSource.setCacheSeconds(3600);

        // 设置未找到消息时返回的默认消息
        messageSource.setUseCodeAsDefaultMessage(false);

        // 设置消息文件找不到Locale时是否抛出异常
        messageSource.setFallbackToSystemLocale(false);

        return messageSource;
    }

    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor(LocalValidatorFactoryBean validatorFactory) {
        MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
        processor.setValidator(validatorFactory.getValidator());
        return processor;
    }

}
